#include "Satory.h"
#include <QDir>
#include <QDateTime>
#include "WindowManager.h"
#include "KeyGetWindow.h"
#include "PeopleWindow.h"
    Sync* Sync::mInstance=0;
    void Sync::Create()
    {
        mInstance=new Sync();
    }

    void Sync::Free()
    {
        delete mInstance;
        mInstance=0;
    }



    Sync::ForbidList& Sync::AddRule(RequestTypes state)
    {

        RulesMap::iterator it=mInstance->mRules.find(state);
        if(it==mInstance->mRules.end())
        {
            mInstance->mRules.insert(RulesMap::value_type(state,ForbidList()));
            it=mInstance->mRules.find(state);
            return it->second;
        }
        else
            return it->second;
    }
   Sync::ForbidList& Sync::ForbidList::operator<<(RequestTypes f)
    {
        push_back(f);
        return *this;
    }


    bool Sync::AddState(RequestTypes state)
    {
        list<RequestTypes>::iterator acts=mInstance->mActions.begin();
        while(acts!=mInstance->mActions.end())
        {
            RulesMap::iterator it=mInstance->mRules.find(*acts);
            if(it!=mInstance->mRules.end())
            {
                if(*acts==it->first)
                    return false;
                list<RequestTypes>::iterator itr=it->second.begin();
                while(itr!=it->second.end())
                {
                    if(state==*itr)
                        return false;
                    itr++;
                }
            }
            acts++;
         }
       mInstance->mActions.push_back(state);
        return true;
    }

    void Sync::RemoveState(RequestTypes state)
   {
        list<RequestTypes>::iterator itr=mInstance->mActions.begin();
        while(itr!=mInstance->mActions.end())
        {
            if(state==*itr)
               {
                  mInstance->mActions.erase(itr);
                  break;
               }
            itr++;
        }
    }

Satory* Satory::mInstance=0;
Satory::Satory():isConnected(false),mBlockSize(0),mRequestCounter(0)
{

    mSocket=new QSslSocket(this);
   connect(mSocket, SIGNAL(readyRead()), this, SLOT(OnReceiveDataBlock()));
   connect(mSocket, SIGNAL(connected()), this, SLOT(OnConnect()));
   connect(mSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect()));
   connect(mSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(OnError(QAbstractSocket::SocketError)));
   mSocket->connectToHost("127.0.0.1",7777);
    QTcpSocket::SocketError err=mSocket->error();
 }
void Satory::Create()
{
    mInstance=new Satory();
}
void Satory::Free()
{
    delete mInstance;
    mInstance=0;
}

Satory::~Satory()
{

}

void Satory::OnConnect()
{
    isConnected=true;
}

void Satory::OnDisconnect()
{
    isConnected=false;
}
void Satory::OnReceiveDataBlock()
{

    if(!mBlockSize)
    {
        if(mSocket->bytesAvailable()<sizeof(quint32))
            return;
        else
        {
            for(int i=0;i<sizeof(quint32);i++)
                mSocket->read(((char*)&mBlockSize)+3-i,1);// прочли размер пакета
        }
    }
    if(mBlockSize)
    {
        quint32 avail = mSocket->bytesAvailable();
        if(avail<mBlockSize)
            return;
        else
        {
            char* data=new char[mBlockSize+1];
             data[mBlockSize]=0;
             mSocket->read(data,mBlockSize);

             Json::Reader reader;
             Json::Value root;
             bool success=reader.parse(data,root,false);



            mBlockSize=0;
            ReceiveNotification(root);
        }

    }

}
bool Satory::SendMessage(const std::string& st)
{
   
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    quint32 len=st.length();
/*
    QFile fil(GetAppPath()+"dump.dat");
    fil.open(QFile::ReadWrite);
    out.setDevice(&fil);
    out << len << st.c_str();
    fil.close();
*/
    for(int i=0;i<sizeof(quint32);i++)
        mSocket->write(((char*)&len)+3-i,1);
    mSocket->write(st.c_str(),st.length());
    return true;
}

void Satory::OnError(QAbstractSocket::SocketError socketError)
{

}
void Satory::ResetRSA()
{
    mCrypter.ResetRSA();
}

void Satory::SaveKey(const std::string& key)
{
    QString filename("key_");
    QDateTime mTime(QDateTime::currentDateTime());
    filename+=mTime.toString("dd_MM_yyyy_hh_mm_ss")+".dat";

    QString appPath=Satory::GetInstance()->GetAppPath();


    filename=appPath+filename;

    QFile f(filename);
    bool val= f.open(QFile::ReadWrite);
    QString err=f.errorString();
    quint64 size=f.write(key.c_str(),key.length());
    f.close();
}

bool Satory::CreateKeys(DataBlock &pbc,DataBlock &pbs,DataBlock &prc,DataBlock &prs,DataBlock &pr_enc,QString pass)
{
    mCrypter.GenRSAKeys(pbc,pbs,
                        prc,prs);
    pr_enc.Create(prc.GetLength()+prs.GetLength());
    unsigned short key_len=prc.GetLength();
    memcpy(pr_enc.Get(),prc.Get(),prc.GetLength());
    memcpy(pr_enc.Get()+prc.GetLength(),prs.Get(),prs.GetLength());

    mCrypter.encode(Base64,pbc,pbc);
    mCrypter.encode(Base64,pbs,pbs);

    Crypter passCrypter;
    DataBlock mPass;
    mPass.CreateFromStr(pass.toStdString().c_str(),false);
    hash_state md;
    unsigned char bf[BIT384];
    sha384_init(&md);
    sha384_process(&md,mPass.Get(),mPass.GetLength());
    sha384_done(&md,bf);
    DataBlock mHashPass,mHashIV,mHashAuth;
    mHashPass.CreateFrom(bf,BIT128);
    mHashIV.CreateFrom(bf+BIT128,BIT128);
    mHashAuth.CreateFrom(bf+BIT256,BIT128);
    passCrypter.AcceptAESKeys(mHashPass,mHashIV,mHashAuth);


    hash_state dm;
    unsigned char  buf[BIT256];//256-bit
    sha256_init(&dm);
    sha256_process(&dm,pr_enc.Get(),pr_enc.GetLength());
    sha256_done(&dm,buf);
    pr_enc.Add(buf,BIT256);
    pr_enc.Add((unsigned const char*)&key_len,2);
    passCrypter.encode(AES,pr_enc,pr_enc);

    mCrypter.encode(Base64,pr_enc,pr_enc);
    return true;
}

bool Satory::Register(QString id,QString email,QString pass,bool store)
{
    if(!Sync::AddState(TRegisterRequest))
        return false;
    SetName(id.toStdString());
    DataBlock private_key;
    if(!CreateKeys(publicKey.cipher,publicKey.sign,
                   privateKey.cipher,privateKey.sign,
                   private_key,pass))
       {
            Sync::RemoveState(TRegisterRequest);
            SetName("");
            return false;
       }
    SetName("");
    RegisterRequest* request=new RegisterRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="userRegister";
    root["params"]["userId"]=id.toStdString();
    root["params"]["email"]=email.toStdString();
    root["params"]["encryptionKey"]=std::string((char*)publicKey.cipher.Get());
    root["params"]["signatureKey"]=std::string((char*)publicKey.sign.Get());
    if(store)
       root["params"]["privateKeyEncrypted"]=std::string((char*)private_key.Get());

    request->SetKey(std::string((char*)private_key.Get()));

    root["id"]=mRequestCounter;
    Json::FastWriter writer;

    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        delete request;
        Sync::RemoveState(TRegisterRequest);
        SetName("");
        return false;
     }
    return true;

}
#include <QProcess>
#include <QDir>
void Satory::InitDataFolder()
{
#ifdef WIN32
    std::string apppathcode = "APPDATA=";
#else
    std::string apppathcode = "HOME=";
   #endif
    QStringList env=QProcess::systemEnvironment();
    QStringList::const_iterator constIterator;
   for (constIterator = env.constBegin(); constIterator != env.constEnd();++constIterator)
   {
       str data=(*constIterator).toLocal8Bit().constData();
       int c=data.find(apppathcode);
       if(c>=0)
       {
           data.replace(apppathcode.c_str(),"");
           str folder=data;
           #ifdef WIN32
                 folder+="\\PhoenixMessenger\\";
            #else
                 folder+="/PhoenixMessenger/";
            #endif
            QDir dir(folder.c_str());
            if(!dir.exists())
            {
                QDir folder(data.c_str());
                folder.mkdir("PhoenixMessenger");
            }

       }

   }
}

QString Satory::GetAppPath()
{
#ifdef WIN32
    std::string apppathcode = "APPDATA=";
#else
    std::string apppathcode = "HOME=";
   #endif
    QStringList env=QProcess::systemEnvironment();
    QStringList::const_iterator constIterator;
       for (constIterator = env.constBegin(); constIterator != env.constEnd();++constIterator)
       {
           str data=(*constIterator).toLocal8Bit().constData();
           int c=data.find(apppathcode);
           if(c>=0)
           {
               data.replace(apppathcode.c_str(),"");
               #ifdef WIN32
                     data+="\\PhoenixMessenger\\";
                     if(userId.length())
                         data=data+"\\"+userId.c_str()+"\\";
                #else
                     data+="/PhoenixMessenger/";
                     if(userId.length())
                         data=data+"/"+userId.c_str()+"/";
                #endif
               return data.c_str();
           }

       }
}

RSAKey& Satory::GetMyKey()
{
    return privateKey;
}

bool Satory::LoadKey(QString pass,ErrorCode &error)
{


    QString appPath=GetAppPath();
    QDir dir(appPath);
    bool ex=dir.exists();


    QFileInfo cur; bool first=false;
    QFileInfoList  files=dir.entryInfoList();
    QFileInfoList::iterator it;
    for( it=files.begin();it!=files.end();it++)
    {
        if(it->isFile())
        {

            str name=it->fileName().toStdString().c_str();
            int n=name.find("key_");
            if(n>=0)
            {
                if(!first)
                {
                    first=true;
                    cur=*it;
                }
                else
                {
                    str cur_name=cur.fileName().toStdString();
                    cur_name.replace("key_","");
                    cur_name.replace(".dat","");

                    name.replace("key_","");
                    name.replace(".dat","");

                    QDateTime cur_time,this_time;
                    QString test1,test2;
                    cur_time=QDateTime::fromString(cur_name.c_str(),"dd_MM_yyyy_hh_mm_ss");
                    test1=cur_time.toString("dd_MM_yyyy_hh_mm_ss");
                    this_time=QDateTime::fromString(name.c_str(),"dd_MM_yyyy_hh_mm_ss");
                    test2=this_time.toString("dd_MM_yyyy_hh_mm_ss");
                    if(this_time>cur_time)
                        cur=*it;

                }
            }

        }
    }
    if(first)
    {

        Crypter passCrypter;
        DataBlock mPass;
        mPass.CreateFromStr(pass.toStdString().c_str(),false);
        hash_state md;
        unsigned char bf[BIT384];
        sha384_init(&md);
        sha384_process(&md,mPass.Get(),mPass.GetLength());
        sha384_done(&md,bf);
        DataBlock mHashPass,mHashIV,mHashAuth;
        mHashPass.CreateFrom(bf,BIT128);
        mHashIV.CreateFrom(bf+BIT128,BIT128);
        mHashAuth.CreateFrom(bf+BIT256,BIT128);
        passCrypter.AcceptAESKeys(mHashPass,mHashIV,mHashAuth);

        QFile f(appPath+cur.fileName());
        f.open(QFile::ReadOnly);

        DataBlock key(f.size());
        f.read((char*)key.Get(),f.size());
        f.close();

        passCrypter.decode(Base64,key,key);
        passCrypter.decode(AES,key,key);

        DataBlock hash,private_key;
        hash.CreateFrom(key.Get()+key.GetLength()-BIT256-2,BIT256);
        private_key.CreateFrom(key.Get(),key.GetLength()-BIT256-2);
        unsigned short key_len;
        memcpy(&key_len,key.Get()+key.GetLength()-2,2);
        hash_state dm;
        unsigned char buf[BIT256];
        sha256_init(&dm);
        sha256_process(&dm,private_key.Get(),private_key.GetLength());
        sha256_done(&dm,buf);
        if(!memcmp(hash.Get(),buf,BIT256))
        {
            DataBlock privat;
            privat.CreateFromBlock(private_key);
            mCrypter.encode(Base64,mPass,mPass);

            mCrypter.encode(Base64,privat,privat);
            /**/
            /*RegisterRequest* request = new RegisterRequest(this);
            Json::Value& root=request->Get();
            root["jsonrpc"]="2.0";
            root["method"]="setPass";
            root["params"]["privateKeyEncrypted"]=std::string((char*)privat.Get());
            root["params"]["len"]=key_len;

            request->SetKey(std::string((char*)privat.Get()));

            root["id"]="-1";
            Json::FastWriter writer;

            SendMessage(writer.write(root));
            delete request;

               */
            /**/

            privateKey.cipher.CreateFrom(private_key.Get(),key_len);
            privateKey.sign.CreateFrom(private_key.Get()+key_len,private_key.GetLength()-key_len);
            mCrypter.AcceptRSAKeys(privateKey.cipher,privateKey.sign);
            return true;

        }
        else
        {
            error=INCORRECT_PASSWORD;
            return false;
         }

    }
    else
    {
        error=NO_KEYS_FOUND;
        return false;
    }
    return false;
}
void Satory::OnRetry()
{
   WindowManager::GetInstance()->CloseWindow(WindowManager::CHOICE_WINDOW);
}


void Satory::OnReset()
{
    WindowManager::GetInstance()->CloseWindow(WindowManager::CHOICE_WINDOW);
    WindowManager::GetInstance()->ShowWindow(WindowManager::KEYGETWINDOW);
}
void Satory::SetName(std::string name)
{

    QString path=GetAppPath();
    path+=name.c_str();
    QDir dir(path);
    QDir base(GetAppPath());
    if(!dir.exists())
        base.mkdir(QString(name.c_str()));

    userId=name;
}

bool Satory::Login(QString id,QString pass)
{
    if(!Sync::AddState(TLoginRequest))
        return false;
    SetName(id.toStdString());
    ErrorCode error;
    if(!mCrypter.IsRSAInit())
        if(!LoadKey(pass,error))
        {
            if(error==NO_KEYS_FOUND)
            {
                KeyGetWindow* win=(KeyGetWindow*)WindowManager::GetInstance()->ShowWindow(WindowManager::KEYGETWINDOW);
                if(win)
                    win->SetIncomingData(id,pass);
            }
            else
            {
                ChoiceWindow* win=(ChoiceWindow*)WindowManager::GetInstance()->ShowWindow(WindowManager::CHOICE_WINDOW);
                win->SetText("Incorrect password! Try again or reset key?");
                win->SetFirst("Try");
                win->SetSecond("Reset");
                connect(win,SIGNAL(onFirstClicked()),this,SLOT(OnRetry()));
                connect(win,SIGNAL(onSecondClicked()),this,SLOT(OnReset()));
            }
            Sync::RemoveState(TLoginRequest);
            SetName("");
            return false;
        }

    DataBlock session,sign,sign_orig;
    session.CreateFrom((unsigned char*)mSessionId.c_str(),mSessionId.length()+1);
    mCrypter.decode(Base64,session,session);
    mCrypter.calcSign(session,sign);
    mCrypter.encode(Base64,sign,sign);

    LoginRequest* request = new LoginRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="userLogin";
    root["params"]["userId"]=id.toStdString().c_str();
    root["params"]["signature"]=std::string((char*)sign.Get());
    root["params"]["version"]="0.1";
    root["params"]["agent"]["name"]="PhoenixMessenger";
    root["params"]["agent"]["version"]="0.1";
    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        Sync::RemoveState(TLoginRequest);
        delete request;
        SetName("");
        return false;
    }
    return true;
}
bool Satory::ResetKey(QString emailcode,QString user,QString pass,bool store)
{
    if(!Sync::AddState(TResetKeyRequest))
        return false;

    DataBlock private_key;
    if(!CreateKeys(publicKey.cipher,publicKey.sign,
                   privateKey.cipher,privateKey.sign,
                   private_key,pass))
       {
            Sync::RemoveState(TRegisterRequest);
            return false;
       }
    ResetKeyRequest* request=new ResetKeyRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="userResetKey";
    root["params"]["userId"]=user.toStdString();
    root["params"]["emailCode"]=emailcode.toStdString();
    root["params"]["encryptionKey"]=std::string((char*)publicKey.cipher.Get());
    root["params"]["signatureKey"]=std::string((char*)publicKey.sign.Get());
    if(store)
       root["params"]["privateKeyEncrypted"]=std::string((char*)private_key.Get());

    request->SetKey(std::string((char*)private_key.Get()));

    root["id"]=mRequestCounter;
    Json::FastWriter writer;

    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        delete request;
        Sync::RemoveState(TResetKeyRequest);
        return false;
     }
    return true;

    return true;
}
 bool Satory::PublicKeyGet(QString userId)
 {
     if(!Sync::AddState(TPublicKeyGetRequest))
         return false;
     PublicKeyGetRequest* request=new PublicKeyGetRequest(this);
     Json::Value& root=request->Get();
     root["jsonrpc"]="2.0";
     root["method"]="publicKeyGet";
     root["params"]["userId"]=userId.toStdString().c_str();


     root["id"]=mRequestCounter;
     Json::FastWriter writer;
     if(SendMessage(writer.write(root)))
     {
         mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
         mRequestCounter++;
     }
     else
     {
         delete request;
         Sync::RemoveState(TPublicKeyGetRequest);
         return false;
     }

     return true;
 }

bool Satory::PrivateKeyGet(QString emailcode,QString user)
{
    if(!Sync::AddState(TPrivateKeyGetRequest))
        return false;
    PrivateKeyGetRequest* request=new PrivateKeyGetRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="privateKeyGet";
    root["params"]["userId"]=user.toStdString().c_str();
    root["params"]["emailCode"]=emailcode.toStdString().c_str();

    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        delete request;
        Sync::RemoveState(TPrivateKeyGetRequest);
        return false;
    }
    return true;
}
bool Satory::Verify(QString id)
{
    if(!Sync::AddState(TVerifyRequest))
        return false;
    VerifyRequest* request=new VerifyRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="userRequestVerify";
    root["params"]["userId"]=id.toStdString().c_str();

    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        delete request;
        Sync::RemoveState(TVerifyRequest);
        return false;
    }
    return true;
}
bool Satory::AskAuth(QString user,ChatKey& key,QString message)
{
    if(!Sync::AddState(TAskAuthRequest))
        return false;

    AskAuthRequest* request=new AskAuthRequest(this);
    Json::Value& root=request->Get();

    root["jsonrpc"]="2.0";
    root["method"]="authorizationAsk";
    root["params"]["userId"]=user.toStdString().c_str();
    root["params"]["sendKey"]["keyEncrypted"] = std::string((char*)key.encKey.Get());
    root["params"]["sendKey"]["keySignature"] = std::string((char*)key.signKey.Get());
    root["params"]["sendKey"]["keyEncryptedForMe"] = std::string((char*)key.encKeyForMe.Get());
    root["params"]["textEncrypted"]=message.toStdString();

    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;

    }
    else
    {
        delete request;
        Sync::RemoveState(TAskAuthRequest);

        return false;
    }

    return true;
}
bool Satory::ConfirmAuth(QString user,ChatKey& key, QString message)
{
    if(!Sync::AddState(TConfirmAuthRequest))
        return false;

    ConfirmAuthRequest* request=new ConfirmAuthRequest(this);
    Json::Value& root=request->Get();

    root["jsonrpc"]="2.0";
    root["method"]="authorizationConfirm";
    root["params"]["userId"]=user.toStdString().c_str();
    root["params"]["sendKey"]["keyEncrypted"] = std::string((char*)key.encKey.Get());
    root["params"]["sendKey"]["keySignature"] = std::string((char*)key.signKey.Get());
    root["params"]["sendKey"]["keyEncryptedForMe"] = std::string((char*)key.encKeyForMe.Get());
    root["params"]["textEncrypted"]=message.toStdString();

    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
       }
    else
    {
        delete request;
        Sync::RemoveState(TConfirmAuthRequest);
        return false;
    }

    return true;
    return true;
}
bool Satory::DeleteAuth(QString user)
{
return true;
}
bool Satory::SendMessage(QString user,QString message,quint64 counter)
{
    if(!Sync::AddState(TSendMessageRequest))
        return false;
    SendMessageRequest* request=new SendMessageRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="messageSend";
    root["params"]["userId"]=user.toStdString().c_str();
    root["params"]["counter"]=counter;
    root["params"]["textEncrypted"]=message.toStdString();
    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        delete request;
        Sync::RemoveState(TSendMessageRequest);
        return false;
    }
    return true;

}
bool Satory::MessageMarkRead(QString user,QString messageid)
{
return true;
}
bool Satory::HistoryGet(QString userId,int skip)
{
return true;
}
bool Satory::ChatKeyGet(QString userId)
{
    if(!Sync::AddState(TChatKeyGetRequest))
        return false;
    ChatKeyGetRequest* request=new ChatKeyGetRequest(this);
    Json::Value& root=request->Get();
    root["jsonrpc"]="2.0";
    root["method"]="chatKeyGet";
    root["params"]["userId"]=userId.toStdString().c_str();

    root["id"]=mRequestCounter;
    Json::FastWriter writer;
    if(SendMessage(writer.write(root)))
    {
        mRequests.insert(map<long,BaseRequest*>::value_type(mRequestCounter,request));
        mRequestCounter++;
    }
    else
    {
        delete request;
        Sync::RemoveState(TChatKeyGetRequest);
        return false;
    }

    return true;
}

bool Satory::UserProfileGet(QString userId)
{
return true;
}
bool Satory::UserUpdateProfile(QString profile)
{
return true;
}

BaseRequest* Satory::GetTopRequest()
{
    if(mRequests.size())
        return mRequests[mRequestCounter-1];
    else
        return 0;
}

void Satory::ReceiveNotification(Json::Value root)
{
    QString id=root["id"].asString().c_str();
    map<long,BaseRequest*>::iterator it=mRequests.find(id.toInt());
    if(it!=mRequests.end())
    {
        BaseRequest* request=it->second;
        QString error=root["error"]["code"].asString().c_str();
        if(error.length())
            request->OnError(root);
        else
            request->OnAnswer(root);

        delete it->second;
        mRequests.erase(it);
    }
    else
     {
        QString type=root["method"].asString().c_str();
        if(type=="login")
            mSessionId=root["params"]["sessionId"].asString();
        if(type=="message")
        {

            if(root["params"]["kind"]=="AuthRequest")
            {
                Dream* dream=MakeDream(root["params"]["userId"].asString().c_str());
                PeopleWindow* win=dynamic_cast<PeopleWindow*>(WindowManager::GetInstance()->GetWindow(WindowManager::PEOPLEWINDOW));
                if(win)
                {
                    QListWidgetItem* item=win->AddPerson(root["params"]["userId"].asString().c_str());
                    dream->AttachUi(Dream::PERSON,item);
                }
                dream->ConfirmAuth();
                dream->SetAuthStatus(true);
                /*
                if(PublicKeyGet(root["params"]["userId"].asString().c_str()))
                {
                    PublicKeyGetRequest* request=dynamic_cast<PublicKeyGetRequest*>(GetTopRequest());
                    connect(request,SIGNAL(KeyArrived(QString)),this,SLOT(OnKeyArrived(QString)));
                 }*/

             }
            if(root["params"]["kind"]=="AuthConfirm")
            {
                std::string user=root["params"]["userId"].asString();
                list<Dream*>::iterator it=mDreams.begin();
                while(it!=mDreams.end())
                {
                    if((*it)->GetName().toStdString()==user)
                        (*it)->SetAuthStatus(true);
                    it++;
                }

            }
            if(root["params"]["kind"]=="message")
            {
                std::string user=root["params"]["userId"].asString();
                list<Dream*>::iterator it=mDreams.begin();
                while(it!=mDreams.end())
                {
                    if((*it)->GetName().toStdString()==user)
                     {
                        DataBlock data;
                        data.CreateFromStr(root["params"]["textEncrypted"].asString().c_str(),true);
                        (*it)->AcceptMessage(data,root["params"]["counter"].asInt());
                      }
                    it++;
                }

            }
        }

    }
}
Dream* Satory::MakeDream(QString name)
{
    Dream* dream=new Dream(this,name);
    mDreams.push_back(dream);
    return dream;
}

Dream* Satory::GetDream(QString name)
{
    list<Dream*>::iterator it=mDreams.begin();
    while(it!=mDreams.end())
    {
        if((*it)->GetName()==name)
            return *it;
        it++;
    }
    return 0;
}
/*
void Satory::OnKeyArrived(QString name)
{
    ConfirmAuth(name);
}*/


Satory* Satory::GetInstance()
{
    return mInstance;
}
void Satory::InitRoster(QString name)
{
    WindowManager::GetInstance()->CloseWindow(WindowManager::LOGINWINDOW);
    PeopleWindow* win=dynamic_cast<PeopleWindow*>(WindowManager::GetInstance()->ShowWindow(WindowManager::PEOPLEWINDOW));
    win->setWindowTitle(name);
}




